package com.lll.simple.rpc.consumer;

import com.lll.simple.rpc.common.RegistryType;
import com.lll.simple.rpc.registry.RegistryFactory;
import com.lll.simple.rpc.registry.RegistryService;
import org.springframework.beans.factory.FactoryBean;

import java.lang.reflect.Proxy;

/**
 * @Author: liull
 * @Description: FactoryBean可以帮我们实现自定义bean,是一种特殊的工厂bean,通过getObject()方法返回对象，而不是FactoryBean本身
 * @Date: Created in 17:31 2021/1/31
 * @Modified By:
 */
public class RpcReferenceBean implements FactoryBean<Object> {
    private Class<?> interfaceClass;

    private String serviceVersion;

    private String registryType = null;

    private String registryAddr;

    private long timeout;

    // public RpcReferenceBean(Class<?> interfaceClass, String serviceVersion, String registryType, String registryAddr, long timeout,
    // Object object) {
    // this.interfaceClass = interfaceClass;
    // this.serviceVersion = serviceVersion;
    // this.registryType = registryType;
    // this.registryAddr = registryAddr;
    // this.timeout = timeout;
    // this.object = object;
    // }

    private Object object;

    @Override
    public Object getObject() throws Exception {
        return object;
    }

    @Override
    public Class<?> getObjectType() {
        return interfaceClass;
    }

    public void init() throws Exception {
        // TODO 生成动态代理对象并赋值给 object
        RegistryType type = RegistryType.valueOf(registryType);
        RegistryService registryService = RegistryFactory.getInstance(registryAddr, type);
        this.object = Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[] {
                interfaceClass
        }, new RpcInvokeProxy(serviceVersion, timeout, registryService));
    }

    public void setInterfaceClass(Class<?> interfaceClass) {
        this.interfaceClass = interfaceClass;
    }

    public void setServiceVersion(String serviceVersion) {
        this.serviceVersion = serviceVersion;
    }

    public void setRegistryType(String registryType) {
        this.registryType = registryType;
    }

    public void setRegistryAddr(String registryAddr) {
        this.registryAddr = registryAddr;
    }

    public void setTimeout(long timeout) {
        this.timeout = timeout;
    }
}
